探究美国青少年压力

数据故事链接——pythonanywhere

数据清洗 ——请看下文

题记:你会时常感到压力大吗?是谁让你产生了压力?是老师,是父母,是同学而又或是你的男女朋友呢?

image.png

说明:此次交互式可视化分析主要想分析影响青少年压力的客观因素。

思考

  • 相关关系而不是因果关系。压力我们一般都会想到的是学习压力大,期末项目多,补课等。但是否可以突发奇想,也有一些我们意想不到的相关性呢?

数据来源

  • 数据
序号 数据 数据来源
1 青少年压力和心理健康问题 data.world
2 美国各州收入 美国经济分析局
3 青少年摄入营养 联合国粮食及农业组织
  • 相关整理部分截图(具体请看下文“数据清洗”)

输入图片说明

故事结论

  • 在压力频率调查中,有超过8成的青少年不时会有压力,并且超过4成的青少年一直有压力。
  • 根据地区压力大小的对比发现,压力可能与工资水平、成绩绩点,贫困率息息相关。
  • 在角色施加压力中,情侣施加的压力比父母、老师都大。可见情感问题会给青少年带来较多困扰。
  • 角色压力相关关系比较中,父母压力与老师压力性质大致相似。
  • 对于大部分喜欢利用食物缓解压力的人,不喜欢运动缓解压力。
In [31]:
import pandas as pd
pressure = pd.read_csv('./mental_health_poll_updated.csv',encoding='gbk').set_index('问题')
In [69]:
pressure.head(5)
Out[69]:
分类 城市
问题
您多久受到一次压力? 一直 California (not set)
您多久受到一次压力? 一直 Michigan Interlochen
您多久受到一次压力? 一直 Kentucky Middlesboro
您多久受到一次压力? 一直 Connecticut Essex
您多久受到一次压力? 一直 Indiana Ligonier

问题个数

In [71]:
Q_type = set(pressure.index)
Q_type
Out[71]:
{nan, '在压力大时你最想做什么', '您使用什么资源来帮助您减轻压力', '您多久受到一次压力?', '最让您感到压力的是什么?'}
  • 问题一:How often are you stressed 您多久受到一次压力?
  • 问题二:What are you most likely to do when you're stressed ? 最让您感到压力的是什么?
  • 问题三:What resources do you use to help ? 您使用什么资源来帮助您?
  • 问题四:What stresses you out the most ?您最有可能面对什么压力吗?

将Question设为索引

提取问题一

In [73]:
Q1 = pressure.loc['您多久受到一次压力?']
Q1.head()
Out[73]:
分类 城市
问题
您多久受到一次压力? 一直 California (not set)
您多久受到一次压力? 一直 Michigan Interlochen
您多久受到一次压力? 一直 Kentucky Middlesboro
您多久受到一次压力? 一直 Connecticut Essex
您多久受到一次压力? 一直 Indiana Ligonier
In [74]:
list(set(Q1['分类']))
Out[74]:
['很少', '一直', '从不', '有时']
In [75]:
len([Q1['分类'].values[i] for i in range(len(Q1['分类'].values)) if Q1['分类'].values[i] == '从不'])
Out[75]:
2261
In [76]:
columns = 'num'
In [77]:
index = list(set(Q1['分类']))
In [78]:
never_num = len([Q1['分类'].values[i] for i in range(len(Q1['分类'].values)) if Q1['分类'].values[i] == '从不'])
never_num
Out[78]:
2261
In [79]:
rarely_num = len([Q1['分类'].values[i] for i in range(len(Q1['分类'].values)) if Q1['分类'].values[i] == '很少'])
rarely_num
Out[79]:
4370
In [80]:
all_num = len([Q1['分类'].values[i] for i in range(len(Q1['分类'].values)) if Q1['分类'].values[i] == '一直'])
all_num
Out[80]:
16101
In [81]:
sometimes = len([Q1['分类'].values[i] for i in range(len(Q1['分类'].values)) if Q1['分类'].values[i] == '有时'])
sometimes
Out[81]:
13146

提取问题一画扇形图

In [82]:
often_num = pd.DataFrame([never_num,rarely_num,all_num,sometimes])
often_num
Out[82]:
0
0 2261
1 4370
2 16101
3 13146
In [83]:
often_num= often_num.rename(columns={0:'num'})
In [84]:
often_num
Out[84]:
num
0 2261
1 4370
2 16101
3 13146
In [85]:
pie1 = often_num.num
pie1_list = [num for num in often_num['num']]
labels = [index for index in often_num.index]
In [86]:
pie1_list
Out[86]:
[2261, 4370, 16101, 13146]
In [87]:
import plotly as py
import plotly.graph_objs as pygo
py.offline.init_notebook_mode()
fig = {
  "data": [
    {
      "values": pie1_list,
      "labels": labels,
      "domain": {"x": [0, .5]},
      "name": 'How often are you stressed',
      "hoverinfo":"label+percent+name",
      "hole": .5, ## 同心圆宽度
      "type": "pie"
    },],
  "layout": {
        "title":"How often are you stressed",
        "annotations": [
            { "font": { "size": 20},
              "showarrow": False,
              "text": "",
                "x": 0.20,
                "y": 1
            },
        ]
    }
}
py.offline.iplot(fig)

封装函数

In [89]:
import plotly as py
import plotly.graph_objs as pygo
py.offline.init_notebook_mode()
pressure = pd.read_csv('./mental_health_poll_updated.csv',encoding='gbk')
Q_type = set(pressure['问题'])
pressure = pressure.set_index('问题')

def question(question):
    question = question
    for i in range(len(Q_type)):
        
        q = pressure.loc[question]
        index = list(set(q['分类']))
        num = []
        for y in range(len(index)):
           
            type1 = len([q['分类'].values[z] for z in range(len(q['分类'].values)) if q['分类'].values[z] == index[y]])
            num.append(type1)
        df_num = pd.DataFrame(num)
        df_num.index = index
        df_num= df_num.rename(columns={0:'num'})
        pie = df_num.num
        pie_list = [num for num in df_num['num']]
        labels = [index for index in df_num.index]    
        fig = {
      "data": [
        {
          "values": pie_list,
          "labels": labels,
          "domain": {"x": [0, .5]},
          "name": question,
          "hoverinfo":"label+percent+name",
          "hole": .5, ## 同心圆宽度
          "type": "pie"
        },],
      "layout": {
            "title":question,
            "annotations": [
                { "font": { "size": 20},
                  "showarrow": False,
                  "text": "",
                    "x": 0.20,
                    "y": 1
                },
            ]
        }
    }

    return py.offline.iplot(fig)
question("您使用什么资源来帮助您减轻压力")      
In [32]:
len(pressure)
Out[32]:
136160

清除地区和城市空值

In [33]:
pressure1 = pressure[~pressure['洲'].str.contains('(not set)')]
C:\Users\zoe\Anaconda3\lib\site-packages\ipykernel_launcher.py:1: UserWarning: This pattern has match groups. To actually get the groups, use str.extract.
  """Entry point for launching an IPython kernel.
In [34]:
len(pressure1)
Out[34]:
135150
In [35]:
pressure2 = pressure1[~pressure1['城市'].str.contains('(not set)')]
C:\Users\zoe\Anaconda3\lib\site-packages\ipykernel_launcher.py:1: UserWarning: This pattern has match groups. To actually get the groups, use str.extract.
  """Entry point for launching an IPython kernel.

导入教育满意程度数据

In [36]:
poll = pd.read_csv('./pollingData.csv')
poll.head()
Out[36]:
State Yes No Total PercentYes PercentNo
0 Delaware 228 111 339 0.67 0.33
1 New Mexico 108 63 171 0.63 0.37
2 North Carolina 724 429 1153 0.63 0.37
3 Nevada 213 127 340 0.63 0.37
4 Ohio 988 607 1595 0.62 0.38

修改地区名与压力调查数据相同名称

In [37]:
poll = poll.rename(columns = {'State':'洲'})

查找两个数据集不同的地区

In [39]:
set(poll['洲'])^set(pressure2.)
Out[39]:
{'District of Columbia', 'Mississipi', 'Mississippi'}

将压力数据的Mississippi修改为Mississipi

In [40]:
pressure2.loc[pressure2. == 'Mississippi','洲'] = 'Mississipi'
C:\Users\zoe\Anaconda3\lib\site-packages\pandas\core\indexing.py:189: SettingWithCopyWarning: 
A value is trying to be set on a copy of a slice from a DataFrame

See the caveats in the documentation: http://pandas.pydata.org/pandas-docs/stable/indexing.html#indexing-view-versus-copy
  self._setitem_with_indexer(indexer, value)
C:\Users\zoe\Anaconda3\lib\site-packages\ipykernel_launcher.py:1: SettingWithCopyWarning: 
A value is trying to be set on a copy of a slice from a DataFrame

See the caveats in the documentation: http://pandas.pydata.org/pandas-docs/stable/indexing.html#indexing-view-versus-copy
  """Entry point for launching an IPython kernel.
In [41]:
set(poll['洲'])^set(pressure2.)
Out[41]:
{'District of Columbia'}

抽取百分比数据

In [42]:
poll = poll.drop(["Yes","No","Total"],axis = 1)

去除教育满意程度没有的地区

In [43]:
pressure2 = pressure2[~pressure2['洲'].isin(['District of Columbia'])]
pressure2.head()
Out[43]:
分类 城市
问题
您多久受到一次压力? 一直 Michigan Interlochen
您多久受到一次压力? 一直 Kentucky Middlesboro
您多久受到一次压力? 一直 Connecticut Essex
您多久受到一次压力? 一直 Indiana Ligonier
您多久受到一次压力? 一直 Texas Pharr

验证

In [44]:
set(poll['洲'])^set(pressure2.)
Out[44]:
set()

抽取问题"How often are you stressed 您多久受到一次压力?"

In [45]:
often = pressure2.loc['您多久受到一次压力?']
often.head()
Out[45]:
分类 城市
问题
您多久受到一次压力? 一直 Michigan Interlochen
您多久受到一次压力? 一直 Kentucky Middlesboro
您多久受到一次压力? 一直 Connecticut Essex
您多久受到一次压力? 一直 Indiana Ligonier
您多久受到一次压力? 一直 Texas Pharr
In [46]:
combin_all = pd.pivot_table(often,index=['洲','分类'],values=['分类'],aggfunc='count').rename(columns = {'城市':'num'})
In [47]:
combin_all.head()
Out[47]:
num
分类
Alabama 一直 181
从不 29
很少 53
有时 139
Alaska 一直 44

导入经纬度数据

In [48]:
jinwei = pd.read_excel("./jinweidu.xlsx")
jinwei.head()
Out[48]:
lat lon 代码 关键词 Region
0 33.247875 -83.441162 AL 阿拉巴马 Alabama
1 63.694167 170.478889 AK 阿拉斯加 Alaska
2 34.048928 -111.093731 AZ 亚利桑那州 Arizona
3 35.201050 -91.831833 AR 阿肯色州 Arkansas
4 36.778261 -119.417932 CA 加利福尼亚 California

合并压力数据、教育满意程度以及经纬度数据

In [54]:
combin = often.merge(jinwei,left_on='洲',right_on='Region').drop('Region',axis=1)
combin = combin.merge(poll)
combin.head()
Out[54]:
分类 城市 lat lon 代码 关键词 PercentYes PercentNo
0 一直 Michigan Interlochen 42.23 -84.32 MI 密歇根 0.58 0.42
1 一直 Michigan Grand Blanc Township 42.23 -84.32 MI 密歇根 0.58 0.42
2 一直 Michigan Saint Joseph 42.23 -84.32 MI 密歇根 0.58 0.42
3 一直 Michigan Macomb 42.23 -84.32 MI 密歇根 0.58 0.42
4 一直 Michigan Saint Johns 42.23 -84.32 MI 密歇根 0.58 0.42

以压力频率做数据透视表

In [56]:
combin_all = pd.pivot_table(combin,index=['洲','关键词','lat','lon','PercentYes','PercentNo','分类','代码'],values=['分类'],aggfunc='count').rename(columns = {'城市':'num'})
In [57]:
combin_all
Out[57]:
num
关键词 lat lon PercentYes PercentNo 分类 代码
Alabama 阿拉巴马 33.247875 -83.441162 0.56 0.44 一直 AL 181
从不 AL 29
很少 AL 53
有时 AL 139
Alaska 阿拉斯加 63.694167 170.478889 0.61 0.39 一直 AK 44
从不 AK 4
很少 AK 19
有时 AK 65
Arizona 亚利桑那州 34.048928 -111.093731 0.62 0.38 一直 AZ 274
从不 AZ 46
很少 AZ 73
有时 AZ 195
Arkansas 阿肯色州 35.201050 -91.831833 0.59 0.41 一直 AR 167
从不 AR 23
很少 AR 43
有时 AR 156
California 加利福尼亚 36.778261 -119.417932 0.60 0.40 一直 CA 532
从不 CA 76
很少 CA 144
有时 CA 460
Colorado 科罗拉多 -50.026490 -50.026490 0.59 0.41 一直 CO 692
从不 CO 67
很少 CO 187
有时 CO 526
Connecticut 康涅狄格州 41.603220 -73.087749 0.56 0.44 一直 CT 178
从不 CT 37
很少 CT 63
有时 CT 198
Delaware 特拉华 39.907793 -75.387852 0.67 0.33 一直 DE 6
从不 DE 1
... ... ... ... ... ... ... ... ...
Texas 德克萨斯州 31.968599 -99.901813 0.60 0.40 很少 TX 398
有时 TX 1104
Utah 犹他州 39.320980 -111.093731 0.60 0.40 一直 UT 281
从不 UT 29
很少 UT 56
有时 UT 210
Vermont 佛蒙特州 44.558803 -72.577842 0.52 0.48 一直 US-VT 85
从不 US-VT 9
很少 US-VT 14
有时 US-VT 76
Virginia 弗吉尼亚 38.033560 -78.507820 0.59 0.41 一直 VA 290
从不 VA 29
很少 VA 63
有时 VA 183
Washington 华盛顿 38.907192 -77.036871 0.57 0.43 一直 WA 313
从不 WA 40
很少 WA 86
有时 WA 275
West Virginia 西弗吉尼亚 38.597626 -80.454903 0.51 0.49 一直 WV 145
从不 WV 12
很少 WV 27
有时 WV 80
Wisconsin 威斯康星州 43.784440 -88.787868 0.58 0.42 一直 WI 331
从不 WI 24
很少 WI 72
有时 WI 239
Wyoming 怀俄明州 43.075968 -107.290284 0.56 0.44 一直 WY 71
从不 WY 9
很少 WY 22
有时 WY 75

200 rows × 1 columns

计算每个频率的在地区占的百分比

In [58]:
list0 = list(combin_all['num'])
In [60]:
num_count = list((often.groupby(['洲'])['分类'].count()))
In [61]:
len(num_count)
Out[61]:
50
In [62]:
list1 = list(often.groupby(['洲'])['分类'].count())
In [63]:
list2=[]
for i in range(len(list1)):
    list2.append(list1[i])
    list2.append(list1[i])
    list2.append(list1[i])
    list2.append(list1[i])
print(list2)
[402, 402, 402, 402, 132, 132, 132, 132, 588, 588, 588, 588, 389, 389, 389, 389, 1212, 1212, 1212, 1212, 1472, 1472, 1472, 1472, 476, 476, 476, 476, 20, 20, 20, 20, 2981, 2981, 2981, 2981, 1850, 1850, 1850, 1850, 14, 14, 14, 14, 345, 345, 345, 345, 1727, 1727, 1727, 1727, 796, 796, 796, 796, 392, 392, 392, 392, 481, 481, 481, 481, 465, 465, 465, 465, 559, 559, 559, 559, 471, 471, 471, 471, 546, 546, 546, 546, 517, 517, 517, 517, 940, 940, 940, 940, 550, 550, 550, 550, 291, 291, 291, 291, 901, 901, 901, 901, 197, 197, 197, 197, 551, 551, 551, 551, 72, 72, 72, 72, 354, 354, 354, 354, 590, 590, 590, 590, 170, 170, 170, 170, 1169, 1169, 1169, 1169, 1127, 1127, 1127, 1127, 155, 155, 155, 155, 1283, 1283, 1283, 1283, 705, 705, 705, 705, 460, 460, 460, 460, 1109, 1109, 1109, 1109, 95, 95, 95, 95, 380, 380, 380, 380, 177, 177, 177, 177, 1006, 1006, 1006, 1006, 3096, 3096, 3096, 3096, 576, 576, 576, 576, 184, 184, 184, 184, 565, 565, 565, 565, 714, 714, 714, 714, 264, 264, 264, 264, 666, 666, 666, 666, 177, 177, 177, 177]
In [64]:
len(list2)
Out[64]:
200
In [28]:
all_the_time.head()
Out[28]:
Region All the time PercentYes PercentNo
0 Alabama 0.450249 0.56 0.44
1 Alaska 0.333333 0.61 0.39
2 Arizona 0.465986 0.62 0.38
3 Arkansas 0.429306 0.59 0.41
4 California 0.438944 0.60 0.40
In [31]:
import plotly.express as px
import plotly
import plotly.graph_objects as go
import plotly.offline as py
import plotly.express as px

plotly.offline.init_notebook_mode(connected=True)
token = 'pk.eyJ1Ijoieml4aWFuMDMiLCJhIjoiY2s0OXozNjUwMGF1OTNlbzExczA5YzBibCJ9.hXI3YY-r4hW7dwR_4YI_DA'
px.scatter(all_the_time,x='All the time',y='PercentYes',size='PercentYes',color='All the time',color_continuous_scale=px.colors.colorbrewer.OrRd)
In [30]:
combin_all['percent'] = [a/b for a,b in zip(list0,list2)] 
combin_all.head()
Out[30]:
num percent
Region 关键词 lat lon PercentYes PercentNo Event Category
Alabama 阿拉巴马 32.318232 86.902298 0.56 0.44 All the time 181 0.450249
Never 29 0.072139
Rarely 53 0.131841
Sometimes 139 0.345771
Alaska 阿拉斯加 64.200857 -149.493673 0.61 0.39 All the time 44 0.333333

压力频率与成绩相关关系

In [36]:
px.scatter(all_the_time,x='PercentYes',y='All the time',marginal_x='histogram',marginal_y='histogram')

压力等级计算

压力大小计算:利用压力频率,将“一直”设置为0.6、“有时候”设置为0.2、“很少”设置为0.15、“从不”设置为0.05算权重。将压力等级分为四个等级,下面是每个等级分布的地区。

In [93]:
import pandas as pd
pressure_measure = pd.read_csv("./mental.csv",encoding='gbk')
In [94]:
pressure_level.head()
Out[94]:
一直 从不 很少 有时 总和 占比 占比.1 占比.2 占比.3 权重all 0.6 never0.05 rarely 0.15 some0.2 Unnamed: 11 地区压力
0 Delaware 6 1 3 10 20 0.30 0.05 0.15 0.50 0.31 30.50 0.00
1 Alaska 44 4 19 65 132 0.33 0.03 0.14 0.49 0.32 32.16 14.73
2 Florida 1133 276 438 1134 2981 0.38 0.09 0.15 0.38 0.33 33.08 22.91
3 Connecticut 178 37 63 198 476 0.37 0.08 0.13 0.42 0.33 33.13 23.36
4 Maryland 221 66 92 167 546 0.40 0.12 0.17 0.31 0.34 33.53 26.95

根据权重分为四个压力等级,为下拉列表筛选地图

In [95]:
jinwei = pd.read_excel('./jinweidu.xlsx')

pressure_jinwei = pressure_measure.merge(jinwei,left_on='洲',right_on='Region').drop('Region',axis=1)
压力较小=pressure_jinwei[(pressure_jinwei["压力程度"]>0)&(pressure_jinwei["压力程度"]<=25)]
压力一般=pressure_jinwei[(pressure_jinwei["压力程度"]>25)&(pressure_jinwei["压力程度"]<=50)]
压力较大=pressure_jinwei[(pressure_jinwei["压力程度"]>50)&(pressure_jinwei["压力程度"]<=70)]
压力很大=pressure_jinwei[(pressure_jinwei["压力程度"]>70)&(pressure_jinwei["压力程度"]<=100)]
element3=['压力较小','压力一般','压力较大','压力很大']
In [101]:
from flask import Flask, render_template, request
import pandas as pd
import cufflinks as cf
import plotly as py
import plotly.graph_objs as go
import plotly.express as px
fig3 = go.Figure(data=go.Choropleth(
    locations=pressure_jinwei['代码'],##图像绘制需要地区代码
    z=pressure_jinwei['压力程度'].astype(float), ##颜色变化因素
    locationmode='USA-states', ## 选择地图
    colorscale='purpor',
    autocolorscale=False, # hover text
    marker_line_color='white', # line markers between states
    colorbar_title="压力等级",  ## 轴名称
    hovertext=pressure_jinwei['洲']
    ))

fig3.update_layout(
    title={
    'text':'各地区压力等级' ,## 图表标题设置
    'y':0.9,
    'x':0.5,
    'font':{'family':'SimHei', 'size':25},
        'xanchor': 'center',
        'yanchor': 'top'},
    geo = dict(
        scope='usa',
        projection=go.layout.geo.Projection(type = 'albers usa'),
        showlakes=True, # lakes
        lakecolor='rgb(255, 255, 255)'),
    )
py.offline.iplot(fig3)